package com.cndw.kungfu.model.player;

import java.util.Map;
import java.util.concurrent.atomic.AtomicIntegerArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.cndw.kungfu.config.Constants;
import com.cndw.kungfu.config.ConstantsRadio;
import com.cndw.kungfu.domain.Player;
import com.cndw.kungfu.domain.Scene;
import com.cndw.kungfu.exception.ConstAssetException;
import com.cndw.kungfu.exception.ConstGoldException;
import com.cndw.kungfu.exception.ConstGoldTickeException;
import com.cndw.kungfu.exception.ConstTypeException;
import com.cndw.kungfu.ext.TimeProcesser;
import com.cndw.kungfu.model.Context;
import com.cndw.kungfu.vo.PlayerChangeVO;
import com.cndw.kungfu.vo.PlayerReceiveVO;
import com.cndw.rpg.framework.SessionHolder;

@Component
public class PlayerServer {
	@Autowired
	private PlayerManager playerManager;
	@Autowired
	private FriendManager friendManager;

	private static AtomicIntegerArray vocationCounts;

	/**
	 * 从内存里面拿数据
	 * 
	 * @param playerId
	 * @return
	 */
	public Player getByPlayerId(long playerId) {
		if (playerId <= 0) {
			return null;
		}
		Player player = Context.getCacheCenter().getPlayerByPlayerId(playerId);
		if (player != null) {
			player.setLastRead(TimeProcesser.getUnixTime());
		}
		return player;
	}

	/**
	 * 获取playerId
	 * 
	 * @param playerName
	 * @return
	 */
	public long getPlayerId(String playerName) {
		return playerManager.getPlayerIdByPlayerName(playerName);
	}

	public Player getByPlayerName(String playerName) {
		return getByPlayerId(getPlayerId(playerName));
	}

	public long getPlayerIdByAccount(String accountName) {
		return Context.getCacheCenter().getPlayerIdByAcc(accountName);
	}

	/**
	 * 检查用户是否在线
	 * 
	 * @param playerId
	 * @return true:在先，false:离线
	 */
	public boolean isOnline(long playerId) {
		return SessionHolder.getInstance().isOnline(playerId);
	}

	/**
	 * 获取各个职业的数量
	 * 
	 * @return
	 */
	public AtomicIntegerArray getVocationCounts() {
		if (vocationCounts == null) {
			synchronized (PlayerServer.class) {
				if (vocationCounts == null) {
					Map<Integer, Integer> tmpMap = playerManager.getCountsGroupDB();
					int[] tmpCounts = new int[] { 0, 0, 0 };
					if (tmpMap != null) {
						if (tmpMap.containsKey(1)) {
							tmpCounts[0] = tmpMap.get(1);
						}
						if (tmpMap.containsKey(2)) {
							tmpCounts[1] = tmpMap.get(2);
						}
						if (tmpMap.containsKey(3)) {
							tmpCounts[2] = tmpMap.get(3);
						}
					}

					vocationCounts = new AtomicIntegerArray(tmpCounts);
					;
				}
			}
		}
		return vocationCounts;

	}

	/**
	 * 发送获取的消息
	 * 
	 * @param name
	 * @param value
	 * @param playerId
	 */
	public void receive(String name, Object value, long playerId) {
		PlayerReceiveVO receive = new PlayerReceiveVO();
		receive.put(name, value);
		receive.broadcast(playerId);
	}

	public void change(String name, Object value, long playerId) {
		PlayerChangeVO change = new PlayerChangeVO();
		change.put(name, value);
		change.broadcast(playerId);
	}

	/**
	 * 广播当前角色的state给前端
	 * 
	 * @param player
	 */
	public void broadcaseState(Player player) {
		Scene scene = Context.getSceneServer().getSceneById(player.getSceneId());
		if (scene != null) {
			scene.broadcast(player, new Object[] { player.getPlayerId(), player.getState() }, ConstantsRadio.playerState);
		}
	}

	public PlayerDataInfo getDataInfoDB(long playerId) {
		PlayerDataInfo playerDataInfo = playerManager.loadDataInfo(playerId);
		playerDataInfo.initFriendsMap(friendManager.getFriend(playerId));
		return playerDataInfo;
	}

	public boolean registerPlayerIdCard(long playerId, String name, String idcard) {
		return playerManager.registerPlayerIdCard(playerId, name, idcard);
	}

	public void updateFriendName(long frindeId, String nameNew) {
		friendManager.updateFriendName(frindeId, nameNew);
	}

	/**
	 * 消费玩家财富
	 * 
	 * @param player
	 * @param paytype
	 * @param gold
	 * @param goldTicke
	 * @param asset
	 * @throws ConstTypeException
	 *             系统支付设置异常
	 * @throws ConstGoldException
	 *             金币不够
	 * @throws ConstGoldTickeException
	 *             绑定金币不够
	 * @throws ConstAssetException
	 *             财富不够
	 */
	public void constPlayerMoney(Player player, int usePaytype, int paytype, int gold, int goldTicke, int asset, int vipScore) throws ConstTypeException,
			ConstGoldException, ConstGoldTickeException, ConstAssetException {
		if (player == null) {
			throw new ConstTypeException();
		}
		boolean constGold = false;
		boolean constGoldTicke = false;
		boolean constAsset = false;
		boolean constVipScore = false;

		if (paytype == 0 || (usePaytype & paytype) <= 0) {// 是否有这种支付方式
			throw new ConstTypeException();
		}
		// 支付方式包括哪些
		if ((usePaytype & Constants.PAY_GOLD) > 0) {
			constGold = true;
		} else if ((usePaytype & Constants.PAY_GOLDTICKE) > 0) {
			constGoldTicke = true;
		} else if ((usePaytype & Constants.PAY_ASSET) > 0) {
			constAsset = true;
		} else if ((usePaytype & Constants.PAY_VipScore) > 0) {
			constVipScore = true;
		}
		if (constGold) {
			if (gold <= 0) {
				throw new ConstTypeException();
			} else if (player.getGoldAll() < gold) {
				throw new ConstGoldException();
			}
		}
		if (constGoldTicke) {
			if (goldTicke <= 0) {
				throw new ConstTypeException();
			} else if (player.getGoldTicke() < goldTicke) {
				throw new ConstGoldTickeException();
			}
		}
		if (constAsset) {
			if (asset <= 0) {
				throw new ConstTypeException();
			} else if (player.getAsset() < asset) {
				throw new ConstAssetException();
			}
		}

		if (constVipScore) {
			if (vipScore <= 0) {
				throw new ConstTypeException();
			} else if (player.getVipScore() < vipScore) {
				throw new ConstAssetException();
			}
		}

		if (constGold) {
			player.alterGoldAll(-gold);
		}
		if (constGoldTicke) {
			player.alterGoldTicke(-goldTicke);
		}
		if (constAsset) {
			player.alterAsset(-asset);
		}
		if (constVipScore) {
			player.alterVipScore(-vipScore);
		}

	}

	public void notifyClacPlayerProperties(long playerId, int delayTime) {
		final Player player = getByPlayerId(playerId);
		if (player == null || player.getLastPlan() >= TimeProcesser.getUnixTime()) {
			return;
		}

		int clacTime = TimeProcesser.getUnixTime() + delayTime;
		player.setLastPlan(clacTime);

		Runnable r = new Runnable() {

			@Override
			public void run() {
				clacProperties(player);
			}
		};
		Context.getTimerServer().scheduleSeconds(r, delayTime);

	}

	/**
	 * 只计算基础属性 针对注册后提供的简单方法
	 * 
	 * @param player
	 */
	public void initProperties(Player player) {
		PlayerFormula.initProperties(player);
		PlayerFormula.clacScorePlayer(player);
	}

	/**
	 * 计算角色属性
	 * 
	 * @param player
	 */
	public void clacProperties(Player player) {
		try {
			PlayerFormula.clacProperties(player);
			PlayerFormula.clacScore(player);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void clacScore(Player player) {
		PlayerFormula.clacScore(player);
		change(PlayerChangeVO.PLAYER_SCORE, player.getScore(), player.getPlayerId());
	}

}
